package core

import (
	"fmt"
	"sync"
)

var (
	onceAction      sync.Once
	timeSlotActions *TimeSlotActions
)

type TimeSlotActions struct {
	Actions map[uint8]TimeSlotJobs
}

func GetTimeSlotActions() *TimeSlotActions {
	onceAction.Do(func() {
		timeSlotActions = &TimeSlotActions{
			Actions: make(map[uint8]TimeSlotJobs),
		}
		for i := 1; i <= TimeSlotNum; i++ {
			timeSlotActions.Actions[uint8(i)] = NewTimeSlotJobsType()
		}
	})

	return timeSlotActions
}

func (t *TimeSlotActions) RegisterJob(action TimeSlotJob, sliceIndex uint8) {
	if sliceIndex > TimeSlotNum {
		return
	}
	t.Actions[sliceIndex].Register(action)
}

type TimeSlotJob struct {
	Fn  func()
	Msg string
}

func NewTimeSlotJob(fn func(), msg string) *TimeSlotJob {
	return &TimeSlotJob{
		Fn:  fn,
		Msg: msg,
	}
}

type TimeSlotJobs interface {
	Execute()
	Register(TimeSlotJob)
	Information()
}

type TimeSlotJobsType struct {
	Jobs []TimeSlotJob
}

func NewTimeSlotJobsType() TimeSlotJobs {
	return &TimeSlotJobsType{
		Jobs: make([]TimeSlotJob, 0),
	}
}

func (t *TimeSlotJobsType) Execute() {
	for _, job := range t.Jobs {
		job.Fn()
	}
}

func (t *TimeSlotJobsType) Register(job TimeSlotJob) {
	t.Jobs = append(t.Jobs, job)
}

func (t *TimeSlotJobsType) Information() {
	for _, job := range t.Jobs {
		fmt.Println(job.Msg)
	}
}
